package com.lxd.sunso.product.service.impl;


import com.lxd.sunso.common.utils.CRC8Utils;
import com.lxd.sunso.common.utils.PageUtils;
import com.lxd.sunso.common.utils.Query;
import com.lxd.sunso.product.components.ConversionUtil;
import com.lxd.sunso.product.components.OSSClientUtil;
import com.lxd.sunso.product.entity.*;
import com.lxd.sunso.product.service.*;
import com.lxd.sunso.product.vo.LaAndLoVo;
import com.lxd.sunso.product.vo.MachineNameAndIdVo;
import com.lxd.sunso.product.vo.MachineVo;
import com.lxd.sunso.product.vo.MessageVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxd.sunso.product.dao.MachineDao;
import org.springframework.web.multipart.MultipartFile;


@Service("machineService")
public class MachineServiceImpl extends ServiceImpl<MachineDao, MachineEntity> implements MachineService {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private MachineService machineService;

    @Autowired
    private MachinekindService machinekindService;

    @Autowired
    private TemplateService templateService;

    @Autowired
    private ControlrealtimeService controlrealtimeService;

    @Autowired
    private DatatemplateService datatemplateService;

    @Autowired
    private UserService userService;

    @Autowired
    private HistroydataService histroydataService;

    @Autowired
    private AlarmregisterService alarmregisterService;

    @Autowired
    private AlarmhisdataService alarmhisdataService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<MachineEntity> page = this.page(
                new Query<MachineEntity>().getPage(params),
                new QueryWrapper<MachineEntity>()
        );

        PageUtils pageUtils = new PageUtils(page);
        List<MachineEntity> records = page.getRecords();

        List<MachineEntity> collect = records.stream().map(machineEntity -> {
            return getMachineEntity(machineEntity);
        }).collect(Collectors.toList());

        List<MachineVo> machineVos = collect.stream().map(entity -> {
            MachineVo machineVo = new MachineVo();
            BeanUtils.copyProperties(entity, machineVo);
            return machineVo;
        }).collect(Collectors.toList());

        pageUtils.setList(machineVos);
        return pageUtils;
    }

    private MachineEntity getMachineEntity(MachineEntity machineEntity) {
        Long machinekindId = machineEntity.getMachinekind();
        MachinekindEntity machinekindEntity = machinekindService.getById(machinekindId);
        machineEntity.setMachinekindName(machinekindEntity.getMachinenumber());
        machineEntity.setMachinekey(machinekindEntity.getMachinename());
        Long customerid = machineEntity.getCustomerid();
        CustomerEntity customerEntity = customerService.getById(customerid);
        machineEntity.setCustomerName(customerEntity.getCustomername());
        Long templateid = machineEntity.getTemplateid();
        TemplateEntity templateEntity = templateService.getById(templateid);
        machineEntity.setTemplateName(templateEntity.getTemplatename());
        return machineEntity;
    }

    @Override
    public PageUtils search(Map<String, Object> params) {
        IPage<MachineEntity> page = null;
        QueryWrapper<MachineEntity> queryWrapper = new QueryWrapper<>();
        String machineName = (String) params.get("machineName");
        String customerName = (String) params.get("customerName");
        String machineState = (String) params.get("machineState");
        String machineKind = (String) params.get("machineKind");

        if (!StringUtils.isEmpty(machineName)) {
            queryWrapper.eq("MachineName", machineName);
        }
        if (!StringUtils.isEmpty(customerName)) {
            CustomerEntity customer = customerService.getOne(new QueryWrapper<CustomerEntity>().eq("CustomerName", customerName));
            Long id = customer.getId();
            queryWrapper.eq("CustomerID", id);
        }
        if (!StringUtils.isEmpty(machineState)) {
            queryWrapper.eq("MachineState", machineState);
        }
        if (!StringUtils.isEmpty(machineKind)) {
            MachinekindEntity machinekindEntity = machinekindService.getOne(new QueryWrapper<MachinekindEntity>().eq("MachineNumber", machineKind));
            Long id = machinekindEntity.getId();
            queryWrapper.eq("MachineKind", id);
        }

        page = this.page(new Query<MachineEntity>().getPage(params), queryWrapper);

        List<MachineEntity> records = page.getRecords();
        //System.out.println(records);

        List<MachineEntity> collect = records.stream().map(machineEntity -> {
            return getMachineEntity(machineEntity);
        }).collect(Collectors.toList());

        page.setRecords(collect);
        //System.out.println(collect);
        return new PageUtils(page);
    }

    @Override
    public MachineEntity findById(Integer id) {
        MachineEntity machineEntity = this.getById(id);
        return getMachineEntity(machineEntity);
    }

    @Override
    public void newUpdate(MachineEntity machine, MultipartFile file) {
        // MachineEntity machineEntity = this.getOne(new QueryWrapper<MachineEntity>().eq("id", machine.getId()));
        CustomerEntity customerEntity = customerService.getOne(new QueryWrapper<CustomerEntity>().eq("CustomerName", machine.getCustomerName()));

        machine.setCustomerid(customerEntity.getId());

        MachinekindEntity machinekindEntity = machinekindService.getOne(new QueryWrapper<MachinekindEntity>().eq("MachineNumber", machine.getMachinekindName()));

        machine.setMachinekind(machinekindEntity.getId());

        // String customerName = machine.getCustomerid();
        //需要判断数据模板是否发生改变，如果改变的话就要重新设置实时数据
        MachineEntity machineEntity = this.getById(machine.getId());
        TemplateEntity templateEntity = templateService.getOne(new QueryWrapper<TemplateEntity>().eq("TemplateName", machine.getTemplateName()));
        if (machineEntity.getTemplateid() != templateEntity.getId()) {
            //删除原来模板的实时数据
            controlrealtimeService.remove(new QueryWrapper<ControlrealtimeEntity>().eq("MachineId", machineEntity.getId()));
            //TODO  历史数据要不要删除
            histroydataService.remove(new QueryWrapper<HistroydataEntity>().eq("MachineID", machineEntity.getId()));
            //TODO 数据登记点要不要删除
            alarmregisterService.remove(new QueryWrapper<AlarmregisterEntity>().eq("MachineId", machineEntity.getId()));
            //TODO 历史报警的删除
            alarmhisdataService.remove(new QueryWrapper<AlarmhisdataEntity>().eq("MachineId", machineEntity.getId()));

            //新建新的模板实时数据
            List<DatatemplateEntity> entities = datatemplateService.list(new QueryWrapper<DatatemplateEntity>().eq("TemplateID", templateEntity.getId()));
            List<Long> list = entities.stream().map(entity -> {
                return entity.getId();
            }).collect(Collectors.toList());

            for (Long dataTemplateId : list) {
                ControlrealtimeEntity controlrealtimeEntity = new ControlrealtimeEntity();
                controlrealtimeEntity.setMachineid(machine.getId());
                controlrealtimeEntity.setTemplateid(templateEntity.getId());
                controlrealtimeEntity.setDatatemplateid(dataTemplateId);
                controlrealtimeEntity.setRealtimevalue(0 + "");
                controlrealtimeEntity.setOntime(null);
                controlrealtimeService.save(controlrealtimeEntity);
            }
        }
        machine.setTemplateid(templateEntity.getId());

        if (file != null) {
            String imgurl = updateHead(file);
            //System.out.println(imgurl);
            machine.setImgurl(imgurl);
        }
        this.updateById(machine);
    }

    /**
     * 根据用户的Id获取模板ID
     *
     * @param id
     * @return
     */
    @Override
    public List<Long> findTemplateByCustomerId(Long id) {
        List<Long> list = this.baseMapper.findTemplateByCustomerId(id);
        return list;
    }

    /**
     * 存储设备以及初始数据置为0
     *
     * @param machine
     * @return
     */
    @Override
    public int saveAndset(MachineEntity machine) {
        MachineEntity machineEntity = this.getOne(new QueryWrapper<MachineEntity>().eq("MachineName", machine.getMachinename()));
        String hexString = ConversionUtil.StringToHex(machine.getMachinename());
        String s = CRC8Utils.CRC8_REMAXIM(hexString);
        if (machineEntity != null) {
            return 1;
        } else if (!StringUtils.leftPad(s, 2, '0').equalsIgnoreCase(machine.getCrc8())) {
            return 2;
        } else {
            machine.setIsonline(0 + "");
            Long machinekind = machine.getMachinekind();
            MachinekindEntity machinekindEntity = machinekindService.getById(machine.getMachinekind());
            machine.setImgurl(machinekindEntity.getMachineimg());
            this.save(machine);
            Long templateid = machine.getTemplateid();
            List<DatatemplateEntity> entities = datatemplateService.list(new QueryWrapper<DatatemplateEntity>().eq("TemplateID", templateid));
            List<Long> list = entities.stream().map(entity -> {
                return entity.getId();
            }).collect(Collectors.toList());

            for (Long dataTemplateId : list) {
                ControlrealtimeEntity controlrealtimeEntity = new ControlrealtimeEntity();
                controlrealtimeEntity.setMachineid(machine.getId());
                controlrealtimeEntity.setTemplateid(templateid);
                controlrealtimeEntity.setDatatemplateid(dataTemplateId);
                controlrealtimeEntity.setRealtimevalue(0 + "");
                controlrealtimeEntity.setOntime(null);
                controlrealtimeService.save(controlrealtimeEntity);
            }
            return 0;
        }
    }

    @Override
    public Long queryOnByMachineKind(Long id) {
        Long num = this.baseMapper.queryOnByMachineKind(id);
        return num;
    }

    @Override
    public Long queryNumByMachineKind(Long id) {
        Long num = this.baseMapper.queryNumByMachineKind(id);
        return num;
    }

    @Override
    public List<Long> searchTemplateByKind(Long id) {
        List<Long> list = this.baseMapper.searchTemplateByKind(id);
        return list;
    }

    @Override
    public Long queryOnByCustomer(Long id) {
        Long num = this.baseMapper.queryOnByCustomer(id);
        return num;
    }

    @Override
    public Long queryNumByCustomer(Long id) {
        Long num = this.baseMapper.queryNumByCustomer(id);
        return num;
    }

    @Override
    public List<MachineEntity> searchBatchMchine(Map<String, Object> params) {
        String machineName = (String) params.get("machineName");
        String userName = (String) params.get("userName");
        List<MachineEntity> list = null;
        UserEntity userEntity = userService.getUserByUserName(userName);
        MachineEntity machineEntity = machineService.getOne(new QueryWrapper<MachineEntity>().eq("machineName", machineName));
        if (!StringUtils.isEmpty(userName)) {
            CustomerEntity customerEntity = customerService.getById(userEntity.getUserid());
            list = machineService.list(new QueryWrapper<MachineEntity>()
                    .eq("TemplateID", machineEntity.getTemplateid())
                    .eq("CustomerID", customerEntity.getId())
                    .eq("IsOnline", 1));
        } else {
            list = machineService.list(new QueryWrapper<MachineEntity>()
                    .eq("TemplateID", machineEntity.getTemplateid())
                    .eq("IsOnline", 1));
        }
        return list;
    }


    @Override
    public List<MessageVo> getCusMachine() {
        List<CustomerEntity> list = customerService.list();
        List<MessageVo> collect = list.stream().map(entity -> {
            MessageVo messageVo = new MessageVo();
            //顾客的设备总数
            Long num = machineService.queryNumByCustomer(entity.getId());
            messageVo.setName(entity.getCustomername());
            messageVo.setValue(num);
            return messageVo;
        }).sorted(new Comparator<MessageVo>() {
            @Override
            public int compare(MessageVo o1, MessageVo o2) {
                return (int) (o2.getValue() - o1.getValue());
            }
        }).collect(Collectors.toList());
        List<MessageVo> messageVos = new ArrayList<>();
        if (collect.size() > 7) {
            messageVos.addAll(collect.subList(0, 7));
        } else {
            messageVos.addAll(collect);
        }
        Long sum = 0L;
        for (int i = 7; i < collect.size(); i++) {
            sum += collect.get(i).getValue();
        }
        MessageVo messageVo = new MessageVo();
        messageVo.setName("其他");
        messageVo.setValue(sum);
        if (messageVo.getValue() != 0) {
            messageVos.add(messageVo);
        }
        return messageVos;
    }

    @Override
    public List<MessageVo> getCusMachineOn() {
        List<CustomerEntity> list = customerService.list();
        List<MessageVo> collect = list.stream().map(entity -> {
            MessageVo messageVo = new MessageVo();
            //顾客的设备总数
            Long num = machineService.queryOnByCustomer(entity.getId());
            messageVo.setName(entity.getCustomername());
            messageVo.setValue(num);
            return messageVo;
        }).sorted(new Comparator<MessageVo>() {
            @Override
            public int compare(MessageVo o1, MessageVo o2) {
                return (int) (o2.getValue() - o1.getValue());
            }
        }).collect(Collectors.toList());
        List<MessageVo> messageVos = new ArrayList<>();
        if (collect.size() > 7) {
            messageVos.addAll(collect.subList(0, 7));
        } else {
            messageVos.addAll(collect);
        }
        Long sum = 0L;
        for (int i = 7; i < collect.size(); i++) {
            sum += collect.get(i).getValue();
        }
        MessageVo messageVo = new MessageVo();
        messageVo.setName("其他");
        messageVo.setValue(sum);
        if (messageVo.getValue() != 0) {
            messageVos.add(messageVo);
        }
        return messageVos;
    }

    @Override
    public List<MessageVo> getKindMachineAll() {
        List<MachinekindEntity> list = machinekindService.list();
        List<MessageVo> collect = list.stream().map(entity -> {
            MessageVo messageVo = new MessageVo();
            //型号的在线设备
            Long num = machineService.queryNumByMachineKind(entity.getId());
            messageVo.setName(entity.getMachinenumber());
            messageVo.setValue(num);
            return messageVo;
        }).sorted(new Comparator<MessageVo>() {
            @Override
            public int compare(MessageVo o1, MessageVo o2) {
                return (int) (o2.getValue() - o1.getValue());
            }
        }).collect(Collectors.toList());
        List<MessageVo> messageVos = new ArrayList<>();
        if (collect.size() > 7) {
            messageVos.addAll(collect.subList(0, 7));
        } else {
            messageVos.addAll(collect);
        }
        Long sum = 0L;
        for (int i = 7; i < collect.size(); i++) {
            sum += collect.get(i).getValue();
        }
        MessageVo messageVo = new MessageVo();
        messageVo.setName("其他");
        messageVo.setValue(sum);
        if (messageVo.getValue() != 0) {
            messageVos.add(messageVo);
        }
        return messageVos;
    }


    @Override
    public List<MessageVo> getKindMachine() {
        List<MachinekindEntity> list = machinekindService.list();
        List<MessageVo> collect = list.stream().map(entity -> {
            MessageVo messageVo = new MessageVo();
            //型号的在线设备
            Long num = machineService.queryOnByMachineKind(entity.getId());
            messageVo.setName(entity.getMachinenumber());
            messageVo.setValue(num);
            return messageVo;
        }).sorted(new Comparator<MessageVo>() {
            @Override
            public int compare(MessageVo o1, MessageVo o2) {
                return (int) (o2.getValue() - o1.getValue());
            }
        }).collect(Collectors.toList());
        List<MessageVo> messageVos = new ArrayList<>();
        if (collect.size() > 7) {
            messageVos.addAll(collect.subList(0, 7));
        } else {
            messageVos.addAll(collect);
        }
        Long sum = 0L;
        for (int i = 7; i < collect.size(); i++) {
            sum += collect.get(i).getValue();
        }
        MessageVo messageVo = new MessageVo();
        messageVo.setName("其他");
        messageVo.setValue(sum);
        if (messageVo.getValue() != 0) {
            messageVos.add(messageVo);
        }
        return messageVos;
    }

    @Override
    public List<String> getEmail(String machineName) {
        List<String> emails = this.baseMapper.getEmail(machineName);
        return emails;
    }

    @Override
    public List<String> getPhone(String machineName) {
        List<String> emails = this.baseMapper.getPhone(machineName);
        return emails;
    }

    @Override
    public List<Object> getMachineNameAndId(Map<String, Object> params) {
        String customerName = (String) params.get("customerName");
        QueryWrapper<MachineEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(customerName)) {
            CustomerEntity customerEntity = customerService.getOne(new QueryWrapper<CustomerEntity>().eq("CustomerName", customerName));
            queryWrapper.eq("CustomerID", customerEntity.getId());
        }
        List<MachineEntity> list = machineService.list(queryWrapper);
        List<Object> collect = list.stream().map(entity -> {
            MachineNameAndIdVo machineNameAndIdVo = new MachineNameAndIdVo();
            machineNameAndIdVo.setId(entity.getId());
            machineNameAndIdVo.setMachinename(entity.getMachinename());
            return machineNameAndIdVo;
        }).sorted((Comparator.comparing(MachineNameAndIdVo::getMachinename))).collect(Collectors.toList());

        return collect;
    }

    @Override
    public List<LaAndLoVo> getLaAndLo(Map<String, Object> params) {
        String customerName = (String) params.get("customerName");
        QueryWrapper<MachineEntity> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(customerName)) {
            CustomerEntity customerEntity = customerService.getOne(new QueryWrapper<CustomerEntity>().eq("CustomerName", customerName));
            queryWrapper.eq("CustomerID", customerEntity.getId());
        }
        List<MachineEntity> list = machineService.list(queryWrapper);
        List<LaAndLoVo> collect = list.stream().map(entity -> {
            LaAndLoVo laAndLoVo = new LaAndLoVo();
            laAndLoVo.setLat(entity.getLat());
            laAndLoVo.setLng(entity.getLng());
            return laAndLoVo;
        }).collect(Collectors.toList());

        return collect;
    }


    @Override
    public String updateHead(MultipartFile file) {
        if (file == null || file.getSize() <= 0) {
            throw new RuntimeException("file不能为空");
        }
        OSSClientUtil ossClient = new OSSClientUtil();
        String name = null;
        try {
            name = ossClient.uploadImg2Oss(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String imgUrl = ossClient.getImgUrl(name);
        String[] split = imgUrl.split("\\?");
        return split[0];
    }

    @Override
    public void delete(List<Long> asList) {
        for (Long machineId : asList) {
            //删除实时数据
            controlrealtimeService.remove(new QueryWrapper<ControlrealtimeEntity>().eq("MachineId", machineId));
            //删除历史数据
            histroydataService.remove(new QueryWrapper<HistroydataEntity>().eq("MachineId", machineId));
            //删除历史报警
            alarmhisdataService.remove(new QueryWrapper<AlarmhisdataEntity>().eq("MachineId", machineId));
            //删除报警登记
            alarmregisterService.remove(new QueryWrapper<AlarmregisterEntity>().eq("MachineId", machineId));
        }
        //删除设备的信息
        this.removeByIds(asList);
    }


    @Override
    public Map<String, Integer> getData() {
        Map<String, Integer> map = new HashMap<>();
        //获取客户总数
        int customersum = customerService.count();
        map.put("customerSum", customersum);
        //获取设备总数
        int machinesum = machineService.count();
        map.put("machinesum", machinesum);
        //获取在线总数
        int onlinesum = machineService.count(new QueryWrapper<MachineEntity>().eq("IsOnline", 1));
        map.put("onlinesum", onlinesum);
        //获取型号总数
        int kindsum = machinekindService.count();
        map.put("kindsum", kindsum);
        return map;
    }

    @Override
    public List<MachineNameAndIdVo> getOnlineMahcine() {
        List<MachineEntity> entities = this.list(new QueryWrapper<MachineEntity>().eq("IsOnline", "1"));
        List<MachineNameAndIdVo> collect = entities.stream().map(entity -> {
            MachineNameAndIdVo machineNameAndIdVo = new MachineNameAndIdVo();
            BeanUtils.copyProperties(entity, machineNameAndIdVo);
            return machineNameAndIdVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void setunOnline() {
        MachineEntity machineEntity = new MachineEntity();
        machineEntity.setIsonline("0");
        machineService.update(machineEntity, new QueryWrapper<MachineEntity>().eq("Isonline", 1));
    }
}